package org.ourgrid.broker.business.schedulerdata.executor.control;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.ourgrid.broker.business.schedulerdata.SchedulerData;
import org.ourgrid.broker.business.schedulerdata.executor.AcceptTransferExecutor;
import org.ourgrid.broker.business.schedulerdata.executor.AddJobExecutor;
import org.ourgrid.broker.business.schedulerdata.executor.CancelTransferExecutor;
import org.ourgrid.broker.business.schedulerdata.executor.DisposeWorkerExecutor;
import org.ourgrid.broker.business.schedulerdata.executor.FinishRequestExecutor;
import org.ourgrid.broker.business.schedulerdata.executor.GetFileInfoExecutor;
import org.ourgrid.broker.business.schedulerdata.executor.GetFilesExecutor;
import org.ourgrid.broker.business.schedulerdata.executor.HereIsJobStatsExecutor;
import org.ourgrid.broker.business.schedulerdata.executor.JobEndedExecutor;
import org.ourgrid.broker.business.schedulerdata.executor.LoggerExecutor;
import org.ourgrid.broker.business.schedulerdata.executor.OperationSucceedExecutor;
import org.ourgrid.broker.business.schedulerdata.executor.PauseRequestExecutor;
import org.ourgrid.broker.business.schedulerdata.executor.RegisterInterestOnWorkerExecutor;
import org.ourgrid.broker.business.schedulerdata.executor.ReleaseWorkerExecutor;
import org.ourgrid.broker.business.schedulerdata.executor.RemoteExecuteExecutor;
import org.ourgrid.broker.business.schedulerdata.executor.ReportReplicaAccountingExecutor;
import org.ourgrid.broker.business.schedulerdata.executor.RequestWorkersExecutor;
import org.ourgrid.broker.business.schedulerdata.executor.ResumeRequestExecutor;
import org.ourgrid.broker.business.schedulerdata.executor.SchedulerDataExecutorIF;
import org.ourgrid.broker.business.schedulerdata.executor.StartTransferExecutor;
import org.ourgrid.broker.business.schedulerdata.executor.StartWorkExecutor;
import org.ourgrid.broker.business.schedulerdata.executor.UnwantWorkerExecutor;
import org.ourgrid.broker.business.schedulerdata.executor.UpdateSchedulerExecutor;
import org.ourgrid.common.internal.IResponseTO;

public class SchedulerDataExecutorControl implements SchedulerDataExecutorControlIF {

	private static SchedulerDataExecutorControl instance;
	
	
	private Map<String, SchedulerDataExecutorIF> executorMap;

	
	private SchedulerDataExecutorControl() {
		fillMap();
	}
	
	
	public static SchedulerDataExecutorControl getInstance() {
		if (instance == null) {
			instance = new SchedulerDataExecutorControl();
		}
		return instance;
	}
	
	
	private void fillMap() {
		
		this.executorMap = new LinkedHashMap<String, SchedulerDataExecutorIF>();
		
		this.executorMap.put(ACCEPT_TRANSFER, new AcceptTransferExecutor());
		this.executorMap.put(ADD_JOB, new AddJobExecutor());
		this.executorMap.put(CANCEL_TRANSFER, new CancelTransferExecutor());
		this.executorMap.put(DISPOSE_WORKER, new DisposeWorkerExecutor());
		this.executorMap.put(FINISH_REQUEST, new FinishRequestExecutor());
		this.executorMap.put(GET_FILE_INFO, new GetFileInfoExecutor());
		this.executorMap.put(GET_FILES, new GetFilesExecutor());
		this.executorMap.put(JOB_ENDED, new JobEndedExecutor());
		this.executorMap.put(LOGGER, new LoggerExecutor());
		this.executorMap.put(OPERATION_SUCCEED, new OperationSucceedExecutor());
		this.executorMap.put(PAUSE_REQUEST, new PauseRequestExecutor());
		this.executorMap.put(REMOTE_EXECUTE, new RemoteExecuteExecutor());
		this.executorMap.put(REPORT_ACCOUNTING, new ReportReplicaAccountingExecutor());
		this.executorMap.put(REQUEST_WORKERS, new RequestWorkersExecutor());
		this.executorMap.put(RESUME_REQUEST, new ResumeRequestExecutor());
		this.executorMap.put(START_TRANSFER, new StartTransferExecutor());
		this.executorMap.put(START_WORK, new StartWorkExecutor());
		this.executorMap.put(UNWANT_WORKER, new UnwantWorkerExecutor());
		this.executorMap.put(UPDATE_SCHEDULER, new UpdateSchedulerExecutor());
		this.executorMap.put(REGISTER_INTEREST_ON_WORKER, new RegisterInterestOnWorkerExecutor());
		this.executorMap.put(RELEASE_WORKER, new ReleaseWorkerExecutor());
		this.executorMap.put(HERE_IS_JOB_STATS, new HereIsJobStatsExecutor());
	}
	
	public List<IResponseTO> execute(List<SchedulerData> commands) {
		List<IResponseTO> responses = new ArrayList<IResponseTO>();
		
		if (commands != null) {
			for (SchedulerData command : commands) {
				responses.addAll(this.executorMap.get(command.getCommandType()).execute(command));
			}
		}
		
		return responses;
	}

}
